package jam.components;

import jam.beans.Driver;
import jam.beans.Location;
import jam.beans.LocationInstance;
import jam.beans.Route;
import jam.beans.Shuttle;
import jam.beans.Status;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/**
 * Exposes all rest services required by driver application and sb staff client
 */
@RestController
public class ShuttleController {

  private static final Logger LOGGER = LoggerFactory.getLogger(ShuttleController.class);

  @Autowired
  ShuttleDB shuttleDB;

  /**
   * Used by the driver to update the location of his shuttle - this must get called as often as possible.
   */
  @RequestMapping(value = "/updateLocation", method = RequestMethod.POST, consumes = "*/*")
  public Status updateLocation(@Valid @RequestBody LocationInstance locationInstance, BindingResult bindingResult) {
    if (bindingResult.hasErrors()) {
      // handle errors and return
      LOGGER.info(bindingResult.toString() + ":" + bindingResult.getAllErrors());
    } else {
      // Create in DB and return
      storeLocation(locationInstance);
    }

    return new Status("You have 5min to reach No.5 - why are u at Nandos?");
  }

  /*
   * Helper method to store location
   */
  private void storeLocation(LocationInstance locationInstance) {
    LOGGER.debug("Updating shuttle {} with new location", locationInstance.getShuttleId());
    Shuttle shuttle = ShuttleDB.getSbShuttlesMapped().get(locationInstance.getShuttleId());
    LOGGER.debug("Retrieved shuttle {}", shuttle.toString());
    shuttle.setLatestLocation(locationInstance);
    // also store it in DB - for historical tracking.
  }

  /**
   * 2. This is called be the bank employees to find out where the buses for a route are
   **/
  @RequestMapping(value = "/locations/{routeId}")
  public List<Shuttle> retrieveLocation(@PathVariable final String routeId) {
    List<Shuttle> shuttles = new ArrayList<Shuttle>();
    for (Shuttle shuttle : ShuttleDB.getSbShuttlesMapped().values()) {
      if (shuttle.getLatestLocation().getRouteId().equals(routeId)) {
        shuttles.add(shuttle);
      }
    }
    return shuttles;
  }

  @RequestMapping("/sampleUpdateLocation")
  public LocationInstance sampleUpdateLocation() {
    return new LocationInstance(shuttleDB.getD1().getId(), new Date(), shuttleDB.getL1_5simmonds(), shuttleDB.getS1().getId(), shuttleDB.getR1().getId(), true, true);
  }

  @RequestMapping("/getRoutes")
  public List<Route> getRoutes() {
    return ShuttleDB.getSbRoutes();
  }

  @RequestMapping("/getDestinationRoutes")
  public List<Location> getDestinationRoutes() {
    return ShuttleDB.getSbDestinationLocations();
  }

  @RequestMapping("/getDrivers")
  public List<Driver> getDrivers() {
    return ShuttleDB.getSbDrivers();
  }

  @RequestMapping("/getShuttles")
  public List<Shuttle> getShuttles() {
    return ShuttleDB.getSbShuttles();
  }

}